/*
 * File: vfsdriver.c
 *
 * Description: This is a driver program for testing your VFS system using an interaction script as input
 * You need to make additional calls to your respective functions as noted in the comments below
 * Make sure the output you display is exactly as per the given specifications for you. Do NOT print
 * any extra output (like debug messages) in the final version of your driver program. You can use this driver program
 * in a in incremental manner as you keep implementing one operator after another. For operators not yet implemented,
 * you can leave the output as given ("TO_BE_DONE"). So you can use this program as your "main" program for testing purposes.
 *
 * DO NOT write the full code for operators in the driver program! You must only CALL your functions from here.
 *
 * Usage: vfsdriver <scriptfilename>
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"../include/file_descriptor.h" 
#include"../include/free_list.h"
#include"../include/vfs_errorcodes.h"
#include"../include/main_header.h"
#include"../include/narray.h"
#include"../include/trie.h"
#define BUFSIZE 200
#define CMDSIZE 30
#define PARSIZE 100

void createvfs ( char *P1, int P2 );
void mountvfs ( char *P1 );
void unmountvfs ( char *P1 );
void makedir ( char *P1, char *P2 );
void deletedir ( char *P1 );
void movedir ( char *P1, char *P2 );
void listdir ( char *P1, int P2, char *P3 );
void addfile ( char *P1, char *P2, char *P3 );
void listfile ( char *P1, char *P2 );
void updatefile ( char *P1, char *P2 );
void removefile ( char *P1 );
void movefile ( char *P1, char *P2 );
void copyfile ( char *P1, char *P2 );
void exportfile ( char *P1, char *P2 );
void searchfile ( char *P1, char *P2 );
void searchtrie ( char *P1);
void remove_slash(char *str);

void processcommand( char *command, char *P1, char *P2, char *P3 );

int main( int argc, char *argv[] )
{
	vfs_mounted = 0;	
	FILE *scriptfp;
	char linebuffer[BUFSIZE];
	char command[CMDSIZE], par1[PARSIZE], par2[PARSIZE], par3[PARSIZE];
	char *token;

	if( argc != 2 ){
		fprintf(stderr,"Usage: vfsdriver <scriptfile>\n");
		return(1);
	}

	if( (scriptfp=fopen(argv[1],"r")) == NULL ){
		fprintf(stderr,"Unable to open script file: %s\n", argv[1]);
		return(2);
	}

	while( fgets(linebuffer, sizeof(linebuffer), scriptfp) != NULL ){
		/* This output is for debugging... do not uncomment in final version */
		/*
		printf("==================================================\n");
		printf("Processing: %s", linebuffer);
		printf("==================================================\n");
		*/

		/* Remove the extra newline character in the end of line */
		linebuffer[ strlen(linebuffer)-1 ] = '\0';
		
		/* Get the command and the parameters using tokenizer */
		strcpy( command, (token = strtok(linebuffer, " ")) == NULL ? "" : token );
		
		strcpy( par1, (token = strtok(NULL, " ")) == NULL ? "" : token );
		strcpy( par2, (token = strtok(NULL, " ")) == NULL ? "" : token );
		strcpy( par3, (token = strtok(NULL, " ")) == NULL ? "" : token );
		/* printf("Command:%s:p1:%s:p2:%s:p3:%s\n",command, par1, par2, par3); */

		processcommand( command, par1, par2, par3 );
	}
}
 
void processcommand( char *command, char *P1, char *P2, char *P3 )
{
	if( strcmp(command, "createvfs") == 0 ){
		if((strlen(P2) == 0) )
		{
		
			printf("%s%s\n", "createvfs_FAILURE ", ERR_VFS_CREATE_00);    //insufficient argument
			return;
		}
		int size = atoi(P2);
		createvfs (P1,size);
	}
	else if( strcmp(command, "mountvfs") == 0 )
		mountvfs (P1);
	else if( strcmp(command, "unmountvfs") == 0 )
		unmountvfs (P1);
	else if( strcmp(command, "makedir") == 0 )
		makedir (P1,P2);
	else if( strcmp(command, "deletedir") == 0 )
		deletedir (P1);
	else if( strcmp(command, "movedir") == 0 )
		movedir (P1,P2);
	else if( strcmp(command, "listdir") == 0 ){
		if((strlen(P2) == 0) )
		{
		
			printf("%s%s\n", "listdir_FAILURE ", ERR_VFS_LISTDIR_00);    //insufficient argument
			return;
		}
		int flag = atoi(P2);
		listdir (P1,flag,P3);
	}
	else if( strcmp(command, "addfile") == 0 )
		addfile (P1,P2,P3);
	else if( strcmp(command, "listfile") == 0 )
		listfile (P1,P2);
	else if( strcmp(command, "updatefile") == 0 )
		updatefile (P1,P2);
	else if( strcmp(command, "removefile") == 0 )
		removefile (P1);
	else if( strcmp(command, "movefile") == 0 )
		movefile (P1,P2);
	else if( strcmp(command, "copyfile") == 0 )
		copyfile (P1,P2);
	else if( strcmp(command, "exportfile") == 0 )
		exportfile (P1,P2);
	else if( strcmp(command, "searchfile") == 0 )
		searchfile (P1,P2);
	else if( strcmp(command, "searchtrie") == 0 )
		searchtrie (P1);
	else
		printf("Ignoring invalid command %s\n", command);
}

void createvfs ( char *P1, int P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(create_vfs_validate(P1,P2) == 1)
	{
		create_vfs(P1,P2);	
	}
	else
		return;
	//printf("createvfs_TO_BE_DONE\n");
}

void mountvfs ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(mount_vfs_validate(P1) == 1)
	{
		mount_vfs(P1);
	}
	else
		return;
	// printf("------------aftermount-----------------");
	// display_DS();
	//printf("mountvfs_TO_BE_DONE\n");
}

void unmountvfs ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
//	printf("------------Before unmount-----------------");
//	display_DS();
	
	if(unmount_vfs_validate(P1) == 1)
	{
		unmount_vfs(P1);
	}
	else 
		return;
	//printf("unmountvfs_TO_BE_DONE\n");
}

void makedir ( char *P1, char *P2 )
{
	remove_slash(P1);
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	struct node* temp;
	char temp2[150];
	//make_dir_rec(P1,P2);
	makeBSTpath(temp2, P1, P2);
	if(make_dir_validate(P1, P2) == 1)
	{
		make_dir(P1,P2);
	//	printf("------------after make dir-----------------");
	//	dispmlay_DS();
		temp=Searchnarray(temp2);
		if(temp!=NULL)
		printf("%s\n", "makedir_SUCCESS");
	}
	else
		return;
	//printf("------------after make dir-----------------");
	//display_DS();
	//printf("makedir_TO_BE_DONE\n");
}

void deletedir ( char *P1 )
{
	remove_slash(P1);
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	
	if(delete_dir_validate(P1) == 1)
	{
	//	printf("%s\n", "validation done");
		remove_file(P1);
		printf("%s\n", "deletedir SUCCESS");
	//	printf("------------after make dir-----------------");
	//	display_DS();
	}
	else
		return;
         // error code
	//printf("deletedir_TO_BE_DONE\n");
}

void movedir ( char *P1, char *P2 )
{
	
	remove_slash(P1);
	remove_slash(P2);
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	
	if(move_dir_validate(P1,P2) == 1)
	{
	
		move_dir(P1,P2);
		printf("%s\n", "movedir_SUCCESS");
	//	printf("------------after make dir-----------------");
	//	display_DS();
	}
	else
		return;
		
	//printf("movedir_TO_BE_DONE\n");
}

void listdir ( char *P1, int P2, char *P3 )
{
	remove_slash(P1);
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(list_dir_validate(P1,P2,P3) == 1)
	{
		displaystub(P1,P2,P3);
	}
	else 
		return;	
	//printf("listdir_TO_BE_DONE\n");
}

void addfile ( char *P1, char *P2, char *P3 )
{
	remove_slash(P1);
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(add_file_validate(P1,P2,P3) == 1)
	{
		add_file(P1,P2,P3);
		printf("%s\n", "addfile_SUCCESS");
	}
	else 
		return;
	// printf("------------after add file-----------------");
	// display_DS();
	//printf("addfile_TO_BE_DONE\n");
}

void listfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(list_file_validate(P1,P2) == 1)
	{
		fileout(P1,P2,0); 
	}
	else 
		return;	      
}

void updatefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(update_file_validate(P1,P2) == 1)
	{
		update_file(P1,P2);
		printf("%s\n", "updatefile_SUCCESS");
	}
	else 
		return;	
	//printf("updatefile_TO_BE_DONE\n");
}

void removefile ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(remove_file_validate(P1) == 1)
	{
		remove_file(P1);
		printf("%s\n", "removefile_SUCCESS");
	}
	else 
		return;	
	// printf("------------after removefile-----------------");
	// display_DS();
	//printf("removefile_TO_BE_DONE\n");
}

void movefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	char* name;
	name = foldernamefrompath(P2);
	P2 = Findparentpath(P2);
	if(move_file_validate(P1, P2, name) == 1)
	{
		move_file(P1, P2, name);
		printf("%s\n", "movefile_SUCCESS");	
	}
	else 
		return;
	//printf("movefile_TO_BE_DONE\n");
}

void copyfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	
	char* name;

	if(strlen(P2)!= 0)
	{
			
		name = foldernamefrompath(P2);

		P2 = Findparentpath(P2);
	}
	
	
	if(copy_file_validate(P1, P2, name) == 1)
	{

		copy_file(P1,P2,name);
		printf("%s\n", "copyfile_SUCCESS");
	}
	else 
		return;
	//printf("copyfile_TO_BE_DONE\n");
	
}

void exportfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(export_file_validate(P1, P2) == 1)
	{
		fileout(P1,P2,1);       //1 for exportfile
	}
	else 
		return;

	//printf("exportfile_TO_BE_DONE\n");
}

void searchfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(search_file_validate(P1, P2) == 1)
	{
		searchFileInHashTable2(P1,P2);
		printf("%s\n", "searchfile_SUCCESS");
	}
	else 
		return;
	//printf("searchfile_TO_BE_DONE\n");
}

void searchtrie ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
		findInTrie(trieHead, P1);
		printf("%s\n", "searchtrie_SUCCESS");
	//printf("searchfile_TO_BE_DONE\n");
}

void remove_slash(char *str)
{
	int size = strlen(str);
	if(size > 1)
	{
		if(str[size-1] == '/')
		{
			str[size-1] = '\0';
		}
	}
}
